const path = require('path')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const config = require('./webpack.cfg')
const { VueLoaderPlugin } = require('vue-loader')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const eslintWebpackPlugins = require('eslint-webpack-plugin')

// 项目目录
const cwdDir = process.cwd()

function paghName(paths) {
  return path.resolve(cwdDir, paths)
}

// 公共插件
const plugins = [
  // 设置环境变量
  new webpack.DefinePlugin({
    BASE_URL: `"${config.build.public}/"`
  }),
  new HTMLWebpackPlugin({
    template: paghName('./public/index.html'),
    title: 'vue 打包学习',
  }),
  new VueLoaderPlugin(),
  // css 提取
  new MiniCssExtractPlugin(),
]

/**
 * @param {string} baseEnv 执行环境
 * @param {object} env webpack-cli 执行时的环境回调数据
 * */ 
module.exports = (baseEnv, env) => {

  if (env.link) {
    // 添加 lint 配置
    plugins.push(new eslintWebpackPlugins())
  }

  return {
    entry: config.build.entry,
    output: {
      filename: 'js/[name].[contenthash].js',
      path: paghName(config.build.dist),
      publicPath: config.build.publicPath,
      // 打包完成后自动清除 dist 内的老文件
      clean: true,
    },
    optimization: {
      // 设置 moduleId 固定，
      // 防止 moduleId 变更导致 bundle 名称中 hash 值改变
      moduleIds: 'deterministic',
      // 将 runtime 提取出来，确保打包文件的 hash 值不会因为 runtime 的变更而改变
      runtimeChunk: 'single',
      // node_modules 中的文件不会经常修改
      // 将它提取出来
      splitChunks: {
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all',
          },
        },
      },
    },
    devtool: baseEnv == 'build' ? config.build.devtool : config.dev.devtool,
    target: 'web',
    module: {
      rules: [
        {
          test: /\.s[ac]ss$|\.css$/i,
          // 配置 vue CSS Modules 可选写法
          oneOf: [
            // 这里匹配 `<style module>`
            {
              resourceQuery: /module/,
              use: [
                baseEnv == 'build' ? MiniCssExtractPlugin.loader : 'vue-style-loader',
                {
                  loader: 'css-loader',
                  options: {
                    modules: {
                      // 配置经过 CSS Modules 编译后 css 的名称
                      localIdentName: '[local]_[hash:base64:5]',
                    }
                  }
                },
                'sass-loader'
              ]
            },
            // 这里匹配普通的 `<style>` 或 `<style scoped>`
            {
              use: [
                baseEnv == 'build' ? MiniCssExtractPlugin.loader : 'vue-style-loader',
                'css-loader',
                'sass-loader'
              ]
            }
          ],
          // 这个配置没起效，之后在尝试
          // generator: {
          //   filename: 'static/css/[name].[hash][ext]',
          // },
        },
        {
          test: /\.vue$/i,
          loader: 'vue-loader'
        },
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env', { targets: "defaults" }]
              ],
              plugins: ['@babel/plugin-transform-runtime']
            }
          }
        },
        {
          test: /\.(png|svg|jpg|jpeg|gif)$/i,
          type: 'asset/resource',
          generator: {
            filename: 'static/img/[name].[hash][ext]',
          },
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/i,
          type: 'asset/resource',
          generator: {
            filename: 'static/font/[name].[hash][ext]',
          },
        },
      ]
    },
    plugins,
  }
} 
